home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / CDTV / cdtvtools-11 / keeper / keeper.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-24  |  10.2 KB  |  322 lines

  1. /****************************************************************************
  2.  
  3.     Keeper -- written by Ray Lambert for Theta Systems, Inc.
  4.  
  5.     Copyright 1991 Commodore Business Machines, Inc.
  6.  
  7.     Purpose and Usage:
  8.  
  9.         Keeper is meant for use in a startup-sequence file to display a
  10.     picture while booting.  Some applications are quite large and take a
  11.     significant period of time to load.  Unless special steps are taken,
  12.     an application such as this cannot display anything for the user to look
  13.     at until the executable file is completely loaded.  This keeps the user
  14.     waiting and the inactivity makes the load time seem even longer.  This
  15.     practice is not acceptable for a platform such as CDTV were the task of
  16.     keeping the user's attention and preventing the user from becoming bored
  17.     is considered paramount.  Keeper was written to provide a solution to
  18.     this problem.  Keeper should be invoked from your startup-sequence file
  19.     (in the foreground: do not use RUN) with the name of an IFF.ILBM picture
  20.     to be displayed.  Keeper loads the picture and then spawns off a tiny
  21.     task which displays the picture and frees all the resources that are used
  22.     to do so when it is time to remove the picture.  Keeper quits shortly
  23.     after these things are done allowing the remainder of the startup-sequence
  24.     to be executed.  Because keeper runs in the foreground while it is loading
  25.     the picture, there will not be a problem with two processes trying to read
  26.     from the same disk at once (this would slow the boot process considerably).
  27.     Note that this can still occur however if a program gets run in the
  28.     background before keeper is run, and that program reads from the disk
  29.     (this should be avoided).  There are three ways to make keeper remove its
  30.     picture.  First, if keeper is run a second time with the keyword 'QUIT' on
  31.     its command line, keeper will cause a previous copy of itself to terminate.
  32.     Second (and easier), the simple act of loading another View will cause
  33.     keeper to terminate.  Keeper accomplishes this by periodically checking
  34.     the GfxBase->ActiView variable to see if its View has been replaced.  Note
  35.     that because of this it is dangerous for a program to save the active
  36.     View during initialization and then try to restore it later.  Please use
  37.     CloseWorkBench() and OpenWorkBench() instead if possible.  A third method
  38.     of terminating keeper is by Signal()'ing it directly.  Keeper's task can
  39.     be located like this:
  40.  
  41.                        task = FindTask("PicKeeper");
  42.  
  43.     and terminated like this:
  44.  
  45.                        Signal(task,SIGBREAKF_CTRL_C);
  46.  
  47.     Keeper can display any IFF picture including overscan.  Keeper
  48.     automatically compensates for PAL by centering its View appropriately.
  49.     Keeper CANNOT display pictures that require custom copper list code such
  50.     as Dynamic HAM pics.  Keeper reads the CDTV preferences and uses the saved
  51.     screen centering information found there.  If the preferences have not
  52.     been set or are not available (not running on a baby) the centering data
  53.     gets stolen from Intuition's View (actually it is the active View at the
  54.     time keeper runs).
  55.  
  56. ****************************************************************************/
  57.  
  58. #include <stdio.h>
  59. #include "keeper.h"
  60. #include <exec/memory.h>
  61. #include <graphics/gfxbase.h>
  62. #include <graphics/view.h>
  63. #include <proto/exec.h>
  64. #include <proto/graphics.h>
  65. #include <proto/dos.h>
  66. #include "cdtvprefs.h"
  67.  
  68. extern int keeper(struct View *, struct MemList *);
  69.  
  70. struct GfxBase *GfxBase=0;
  71. struct Library *IntuitionBase=0;
  72. struct View *v=0;
  73. struct ViewPort *vp=0;
  74. struct RasInfo *ri=0;
  75. struct BitMap *bm=0;
  76. struct ColorMap *cm=0;
  77. struct BLITmap *pic=0;
  78. struct MemList *ml=0;
  79. BOOL vpmade = FALSE;
  80. struct CDTVPrefs prefs;
  81.  
  82.  
  83. ULONG mlsize;
  84.  
  85. struct MemList *BuildMemList(void)
  86. {
  87.   register struct MemList *ml;
  88.   register struct MemEntry *me;
  89.   register UWORD cnt;
  90.   ULONG size;
  91.  
  92.   cnt = ((pic->d + 4) - 1);
  93.   mlsize = (sizeof(struct MemList) + (cnt * sizeof(struct MemEntry)));
  94.   unless( ml = (struct MemList *)AllocMem(mlsize,MEMF_PUBLIC|MEMF_CLEAR) )
  95.     return(0);
  96.   ml->ml_NumEntries = (cnt + 1);
  97.   me = &ml->ml_ME[0];
  98. /** include all of the blitplanes **/
  99.   size = RASSIZE(pic->w,pic->h);
  100.   for(cnt = 0; cnt < pic->d; cnt++)
  101.     {
  102.       me->me_Addr = (APTR)pic->p[cnt];
  103.       me->me_Length = size;
  104.       me++;
  105.     }
  106. /** include the View struct **/
  107.   me->me_Addr = (APTR)v;
  108.   me->me_Length = sizeof(struct View);
  109.   me++;
  110. /** include the ViewPort struct **/
  111.   me->me_Addr = (APTR)vp;
  112.   me->me_Length = sizeof(struct ViewPort);
  113.   me++;
  114. /** include the RasInfo struct **/
  115.   me->me_Addr = (APTR)ri;
  116.   me->me_Length = sizeof(struct RasInfo);
  117.   me++;
  118. /** include the BitMap struct **/
  119.   me->me_Addr = (APTR)bm;
  120.   me->me_Length = sizeof(struct BitMap);
  121.  
  122.   return(ml);
  123. }
  124.  
  125.  
  126. void say(char *msg)
  127. {
  128.   static BPTR console;
  129.   unless( console ) unless( console = Output() ) return;
  130.   Write(console,msg,strlen(msg));
  131. }
  132.  
  133.  
  134. void xit(char *msg, int rc)
  135. {
  136.   if (ml) FreeMem(ml,mlsize);
  137.   if (pic) unloadILBM(pic);
  138.   if (cm) FreeColorMap(cm);
  139.   if (bm) FreeMem(bm,sizeof(struct BitMap));
  140.   if (ri) FreeMem(ri,sizeof(struct RasInfo));
  141.   if (vpmade)
  142.     {
  143.       if (v->LOFCprList) FreeCprList(v->LOFCprList);
  144.       if (v->SHFCprList) FreeCprList(v->SHFCprList);
  145.       FreeVPortCopLists(vp);
  146.     }
  147.   if (vp) FreeMem(vp,sizeof(struct ViewPort));
  148.   if (v) FreeMem(v,sizeof(struct View));
  149.   if (GfxBase) CloseLibrary(GfxBase);
  150.   if (IntuitionBase) CloseLibrary(IntuitionBase);
  151.   if (msg) say(msg);
  152.   exit(rc);
  153. }
  154.  
  155.  
  156. #if DBG
  157. struct BitDefs
  158. {
  159.   ULONG bd_bit;
  160.   ULONG bd_mask;
  161.   char *bd_text;
  162. }
  163. mode_bits[] =
  164. {
  165.   { (ULONG)HIRES,           (ULONG)HIRES,           "HIRES"           },
  166.   { (ULONG)LACE,            (ULONG)LACE,            "LACE"            },
  167.   { (ULONG)HAM,             (ULONG)HAM,             "HAM"             },
  168.   { (ULONG)EXTRA_HALFBRITE, (ULONG)EXTRA_HALFBRITE, "EXTRA_HALFBRITE" },
  169.   { (ULONG)SPRITES,         (ULONG)SPRITES,         "SPRITES"         },
  170.   { (ULONG)DUALPF,          (ULONG)DUALPF,          "DUALPF"          },
  171.   { (ULONG)PFBA,            (ULONG)PFBA,            "PFBA"            },
  172.   { (ULONG)VP_HIDE,         (ULONG)VP_HIDE,         "VP_HIDE"         },
  173.   { (ULONG)GENLOCK_AUDIO,   (ULONG)GENLOCK_AUDIO,   "GENLOCK_AUDIO"   },
  174.   { (ULONG)GENLOCK_VIDEO,   (ULONG)GENLOCK_VIDEO,   "GENLOCK_VIDEO"   },
  175.   { 0,                      0,                      0,                }
  176. };
  177.  
  178. char *ShowBitDefs(char *buffer, ULONG fbits, struct BitDefs *bd)
  179. {
  180.   register char *buf, *p;
  181.   BOOL flag = FALSE;  /* flag to output a "|" or not */
  182.   if (fbits == NULL)
  183.     {
  184.       strcpy(buffer,"NULL");
  185.       return(buffer);
  186.     }
  187.   buf = buffer;
  188.   while(bd->bd_text != NULL)
  189.     {
  190.       if ((fbits & bd->bd_mask) == bd->bd_bit)
  191.         {
  192.           if (flag)
  193.             *buf++ = '|';
  194.           else
  195.             flag = TRUE;
  196.           for(p = bd->bd_text; *p; p++, buf++) *buf = *p;
  197.         }
  198.       bd++;
  199.     }
  200.   if (!flag)
  201.     {
  202.       sprintf(buffer,"0x%08X",fbits);
  203.       return(buffer);
  204.     }
  205.   *buf = 0;
  206.   return(buffer);
  207. }
  208.  
  209.  
  210. void showpicinfo(void)
  211. {
  212.   char s[200];
  213.   sprintf(s,"Picture:  %hd X %hd X %hd, ",pic->w,pic->h,pic->d);
  214.   say(s);
  215.   ShowBitDefs(s,(pic->modes&(HIRES|LACE|HAM|EXTRA_HALFBRITE)),mode_bits);
  216.   say(s);
  217.   sprintf(s,"\nViewPort: %hd,%hd,%hd,%hd\n",v->DxOffset,v->DyOffset,vp->DWidth,vp->DHeight);
  218.   say(s);
  219. }
  220. #endif
  221.  
  222.  
  223. main(int argc, char *argv[])
  224. {
  225.   short normal, picture, maximum, i;
  226.  
  227.   unless( argc == 2 ) xit("Usage: keeper <picname | QUIT>\n",5);
  228.   if (stricmp(argv[1],"QUIT") == 0)
  229.     {
  230.       register struct Task *t;
  231.       if ( t = FindTask("PicKeeper") ) Signal(t,SIGBREAKF_CTRL_C);
  232.       xit(0,0);
  233.     }
  234.   unless( IntuitionBase = OpenLibrary("intuition.library",0) ) xit(0,255);
  235.   unless( GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0) )
  236.     xit(0,255);
  237.   unless( v = (struct View *)AllocMem(sizeof(struct View),MEMF_PUBLIC|MEMF_CLEAR) )
  238.     xit("No memory for View\n",21);
  239.   unless( vp = (struct ViewPort *)AllocMem(sizeof(struct ViewPort),MEMF_PUBLIC|MEMF_CLEAR) )
  240.     xit("No memory for ViewPort\n",21);
  241.   unless( ri = (struct RasInfo *)AllocMem(sizeof(struct RasInfo),MEMF_PUBLIC|MEMF_CLEAR) )
  242.     xit("No memory for RasInfo\n",21);
  243.   unless( bm = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_PUBLIC|MEMF_CLEAR) )
  244.     xit("No memory for BitMap\n",21);
  245.   unless( cm = GetColorMap(32) ) xit("No memory for ColorMap\n",21);
  246.   unless( pic = loadILBM(argv[1]) ) xit("Unable to load picture\n",21);
  247.   InitView(v);
  248.   InitVPort(vp);
  249.   v->ViewPort = vp;
  250.   vp->RasInfo = ri;
  251.   ri->BitMap = bm;
  252.   BLITmap2BitMap(pic,bm);
  253.  
  254.   vp->ColorMap = cm;
  255.   LoadRGB4(vp,pic->cmap,(1 << pic->d));
  256.  
  257.   maximum = 368;
  258.   if (pic->modes & HIRES) maximum *= 2;
  259.   vp->DWidth = min(pic->w,maximum);
  260.  
  261.   maximum = (GfxBase->DisplayFlags & PAL) ? 283 : 241;
  262.   if (pic->modes & LACE) maximum *= 2;
  263.   vp->DHeight = min(pic->h,maximum);
  264.  
  265.   vp->Modes = (pic->modes & (HIRES|LACE|HAM|EXTRA_HALFBRITE));
  266.   v->Modes = (pic->modes & LACE);
  267.  
  268.   ReadPrefs(&prefs);
  269.  
  270.   normal = GfxBase->NormalDisplayColumns;
  271.   if (normal >= 640) normal /= 2;       /* adjust to LORES pixels */
  272.   picture = vp->DWidth;
  273.   if (vp->Modes & HIRES) picture /= 2;  /* ditto                  */
  274.   if (picture <= normal)
  275.     v->DxOffset = (prefs.DisplayX + ( (normal - picture) / 2));
  276.   else
  277.     v->DxOffset = (prefs.DisplayX - ( (picture - normal) / 2));
  278. /* correct X offset to prevent edge jitters (must be on 8 bit boundary) */
  279.   i = (v->DxOffset % 8);
  280.   if (i > 4)
  281.     {
  282.       v->DxOffset += (8 - i);
  283.     }
  284.   else
  285.     {
  286.       v->DxOffset -= i;
  287.     }
  288.  
  289.   normal = GfxBase->NormalDisplayRows;
  290.   if (normal >= 400) normal /= 2;       /* adjust to LORES pixels */
  291.   picture = vp->DHeight;
  292.   if (vp->Modes & LACE) picture /= 2;   /* ditto                  */
  293.   if (picture <= normal)
  294.     v->DyOffset = (prefs.DisplayY + ( (normal - picture) / 2));
  295.   else
  296.     v->DyOffset = (prefs.DisplayY - ( (picture - normal) / 2));
  297.  
  298.   MakeVPort(v,vp);
  299.   MrgCop(v);
  300.   vpmade = TRUE;
  301.  
  302. #if DBG
  303.   showpicinfo();
  304. #endif
  305.  
  306.   unless( ml = BuildMemList() ) xit("Couldn't create MemList\n",10);
  307.   unless( keeper(v,ml) ) xit("Couldn't create task\n",10);
  308.  
  309. /* keeper will close all of these... */
  310.   vpmade = FALSE;
  311.   v = 0;
  312.   vp = 0;
  313.   ri = 0;
  314.   bm = 0;
  315.   cm = 0;
  316.   pic->d = 0; /* keeper keeps the bit planes */
  317.   ml = 0;
  318.   GfxBase = 0;
  319.   IntuitionBase = 0;
  320.   xit(0,0);
  321. }
  322.